#ifndef __ALLOCATOR_H__
#define __ALLOCATOR_H__
/* Memory allocator
 * [1] Standard allocator : for general purposes
 * [2] Aligned allocator  : for high performance calculation
 */

#include "util/util_config.h"
#include <xmmintrin.h>

NS_UTIL_BEGIN

template<typename T, typename S=int32>
class standard_allocator
{
public:
	typedef T value_type;
	typedef S size_type;
protected:
	value_type* create(size_type sz)
	{
		value_type* ptr = new value_type[sz];
		return ptr;
	}
	void destroy(value_type*& data)
	{
		if(!data)
		{
			delete[] data;
			data = NULL;
		}
	}
	size_type __expand(size_type cur_size)
	{
		return (cur_size<=4)?8:(cur_size*2);
	}
	void __memcopy(value_type* dst, const value_type* src, size_type sz)
	{
		std::memcpy(dst, src, sizeof(value_type)*sz);
	}
	void __memswap(value_type*& dst, value_type*& src)
	{
		value_type* tmp = src;
		src = dst;
		dst = tmp;
	}
};

template<typename T, typename S=int32, int ALIGNMENT = 16>
class aligned_allocator
{
public:
	typedef T value_type;
	typedef S size_type;
protected:
	value_type* create(size_type sz)
	{
		value_type* ptr = (value_type*)_mm_malloc(sizeof(value_type)*sz, ALIGNMENT);
		return ptr;
	}
	void destroy(value_type*& data)
	{
		if(!data)
		{
			_mm_free(data);
			data = NULL;
		}
	}
	size_type __expand(size_type cur_size)
	{
		return (cur_size<=8)?16:(cur_size*2);
	}
	void __memcopy(value_type* dst, const value_type* src, size_type sz)
	{
		if(sz>0)
		{
			std::memcpy(dst, src, sizeof(value_type)*sz);
		}
	}
};

NS_UTIL_END

#endif